﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Threading;

/**
* @author Quentin Leguay 4Info INSA Rennes 
* @date Avril 2010
* @brief La classe Vue est la classe qui contrôle l'affichage
*/
namespace vue{ 

    public class Vue
    {
        /***************/
        /** attributs **/
        /***************/

        // La fenetre qui affiche le programme
        private Form1 fenetre;

        private general.Logiciel logiciel;

        private ThreadRefresh threadRefresh;


        /********************/
        /**  Constructeurs **/
        /********************/

        /**
        * Vue(general.Logiciel _logiciel)
        * @brief Constructeur 
        * @param Logiciel _logiciel : le Logiciel qui créé la vue
        */
        public Vue(general.Logiciel _logiciel)
        {
            logiciel = _logiciel;
            fenetre = new Form1(this);
            
            threadRefresh = new ThreadRefresh(5000, this.fenetre);
            Thread t = new Thread(new ThreadStart(threadRefresh.ThreadLoop));

            t.Start();
        }

        /***************/
        /**  méthodes **/
        /***************/

        /**
        * Run()
        * @brief Fonction appelée au démarage de l'application pour créer l'affichage graphique
        */
        public void Run()
        {
            Application.Run(fenetre);
        }


        /**
        * addBibliothequeBalise(Modele.Balise _balise, System.Drawing.Bitmap new_image_balise)
        * @brief ajoute une balise et son icône à la bibliothèque des balise
        * @param Balise _balise : la balise à ajouter
        * @param System.Drawing.Bitmap _new_image_balise : l'icône associée à la balise
        * @return void
        */
        public void addBibliothequeBalise(Modele.Balise _balise, System.Drawing.Bitmap _new_image_balise)
        {
            logiciel.addBibliothequeBalise(_balise, _new_image_balise);
        }

        /**
        * supprimerCalqueCourant()
        * @brief supprime la calque sélectionné comme "courant"
        * @return void
        */
        public void supprimerCalqueCourant()
        {
            logiciel.supprimerCalqueCourant();
        }

        /**
        * ouvertureNouveauProjet()
        * @brief demande au logiciel de créer un nouveau projet
        * @return void
        */
        public void ouvertureNouveauProjet()
        {
            logiciel.ouvertureNouveauProjet();
        }

        /**
        * refresh()
        * @brief appel au refresh de base du inkPicture de fenetre (pratiquement inutilisé, voir CompleteRefresh())
        * @return void
        */
        public void refresh()
        {
            fenetre.Refresh();
        }

        /**
        * ajouterDocument(System.Drawing.Bitmap document) 
        * @brief ajoute un document à annoter / une image de fond
        * @return void
        */
        public void ajouterDocument(System.Drawing.Bitmap document) 
        {
            logiciel.ajouterDocument(document);
        }


        /**
         * @brief
         * @brief rafraichit (supprime et réaffiche) les strokes de la couche supérieurer (calque courant) de l'InkPicture
         * @param Microsoft.Ink.Ink _ink : l'ink contenant les strokes du calque courant
         * @return void
        */
        public void completeRefresh(Microsoft.Ink.Ink _ink , ArrayList _annotations , ArrayList textes)
        {
            fenetre.completeRefresh(_ink,_annotations,textes);
        }


        /**
         * @brief rafraichit 
         * @brief permet de remonter le rafraichissement Form1->Vue->Logiciel pour ensuite redescendre avec les informations necessaires à la mise à jour
         * @param 
         * @return void
        */
        public void completeRefresh()
        {
            logiciel.completeRefresh();
        }

        /**
        * @brief undo
        * @brief remontée de l'évènement undo
        * @param int nb : le nombre d'annulations (actuellement 0)
        * @return int nb : le nombre d'annulations réalisées
        */
        public int undo(int _nb)
        {
            return logiciel.undo(_nb);
        }


        /**
        * @brief redo
        * @brief remontée de l'évènement redo
        * @param int nb : le nombre d'annulations (actuellement 0)
        * @return int nb : le nombre d'annulations refaites
        * @return void
        */
        public int redo(int _nb)
        {
            return logiciel.redo(_nb);
        }

        /**
        * @brief sendUtilisateur
        * @brief remontée de l'utilisateur
        * @param String _prenom : le prénom de l'utilisateur
        * @param String _nom : le nom de l'utilisateur
        * @return void
        */
        public void sendUtilisateur(string _prenom, string _nom)
        {
            ArrayList listeAuteurs = logiciel.sendUtilisateur(_prenom,_nom);
            fenetre.setUtilisateur(_prenom, _nom);
            fenetre.setComboBoxAuteurs(listeAuteurs);
        }


        /**
         * @brief getFenetre()
         * @brief envoie une référence vers la fenetre principale de la vue
         * @return Form1 fenetre
        */
        public vue.Form1 getFenetre()
        {
            return fenetre;

        }

        /**
         * @brief changerGraphics
         * @brief rafraichit la couche intermédiaire (calques non courants) de l'InkPicture
         * @param Microsoft.Ink.Ink _combinedInk : l'ink contenant les strokes des calques non courants
         * @return void
        */
        public void changerGraphics(Microsoft.Ink.Ink _combinedInk,ArrayList _annotations, ArrayList _textes)
        {
            fenetre.changerGraphics(_combinedInk, _annotations , _textes);
        }



        /*************************
        * Traitement des actions *
        **************************/

        /**
         * ActionZoneDessin(Microsoft.Ink.Stroke _stroke)
         * @brief Appelée lorsque l'utilisateur dépose de l'encre sur le calque
         * @param Strokes _strokes : objet contenant de nombreuses informations (analogue à ensemble de points)
         * @return void
        */
        public void ActionZoneDessin(Microsoft.Ink.Stroke _stroke)
        {
            logiciel. ActionZoneDessin(_stroke);
        }

        /**
         * ActionBouton()
         * @brief Appelée lorsque l'utilisateur appuie sur le bouton du stylet (inutilisée pour l'instant)
         * @return void
        */
        public void ActionBouton()
        {
            logiciel.ActionBouton();
        }

        /**
         * ActionEffacer(Microsoft.Ink.Strokes _strokes)
         * @brief Appelée lorsque l'utilisateur utilise la "gomme" du crayon (bouton à l'opposé de la pointe) (inutilisé pour le moment)
         * @param Strokes _strokes : objet contenant de nombreuses informations (analogue à ensemble de points)
         * @return void
        */
        public void ActionEffacer(Microsoft.Ink.Strokes _strokes)
        {
            logiciel.ActionEffacer(_strokes);
        }


        /**
         * ActionDoubleClic(Microsoft.Ink.Strokes _strokes)
         * 
         * @brief Appelée lorsque l'utilisateur effectue un double clic (inutilisé pour le moment)
         * @param Strokes _strokes : objet contenant de nombreuses informations (analogue à ensemble de points)
         * @return void
        */
        public void ActionDoubleClic(Microsoft.Ink.Strokes _strokes)
        {
            logiciel.ActionDoubleClic(_strokes);
        }


        /**
         * changerMode(Controleur.Mode _mode)
         * 
         * @brief Appelée lorsque l'utilisateur change de mode
         * @param Mode _mode : le nouveau mode à associer au contrôleur
         * @return void
        */
        public void changerMode(Controleur.Mode _mode)
        {
            logiciel.changerMode(_mode);
        }


        /**
         * setModeCouleur(System.Drawing.Color _couleur)
         * 
         * @brief Appelée lorsque l'utilisateur change la couleur de l'encre
         * @param System.Drawing.Color _couleur : la nouvelle couleur à utiliser
         * @return void
        */
        public void setModeCouleur(System.Drawing.Color _couleur)
        {
            logiciel.setModeCouleur(_couleur);
        }


        /**
         * setModeOpacite(int _opacite)
         * 
         * @param int _opacite : la nouvelle opacite à utiliser. Attention, vaut entre 0 et 255
         * @return void
        */
        public void setModeOpacite(int _opacite)
        {
            logiciel.setModeOpacite(_opacite);
        }


        /**
         * setModeEpaisseur(int _epaisseur)
         * 
         * @param int _epaisseur : la nouvelle epaisseur à utiliser. Comprise entre 0 et 200
         * @return void
        */
        public void setModeEpaisseur(int _epaisseur)
        {
            logiciel.setModeEpaisseur(_epaisseur);
        }


        /**
         * changerCalqueCourant(int numero_calque)
         * 
         * @brief Appelée lorsque l'utilisateur change de calque courant
         * @param int numero_calque : le numéro du claque à rendre courant
         * @return void
        */
        public void changerCalqueCourant(int numero_calque)
        {
            logiciel.changerCalqueCourant(numero_calque);

        }


        /**
         * creeCalque()
         * 
         * @brief Appelée lorsque l'utilisateur créé un nouveau calque
         * @param Strokes _strokes : objet contenant de nombreuses informations (analogue à ensemble de points         * @return void
        */
        public void creeCalque()
        {
            logiciel.creeCalque();
        }

        /**
         * changeVisibility(int numero_calque)
         * 
         * @brief Appelée lorsque l'utilisateur change la visibilité d'un calque
         * @param int numero_calque : le numéro du claque dont on change la visibilité
         * @return void
        */
        public void changeVisibility(int numero_calque)
        {
            logiciel.changeVisibility(numero_calque);
        }

        /**
         * clear_balise()
         * 
         * @brief Appelée lorsque l'utilisateur dépose de l'encre sur le calque
         * @return void
        */
        public void clear_balise()
        {
            this.logiciel.clear_balise();
        }

        /**
        *  clear_encre()
        *  
        *  @brief Enlève toute l'encre du calque courant
        *  @return void
        */
        public void clear_encre()
        {
            this.logiciel.clear_encre();
        }


        /**
        *  clear_texte()
        *  
        *  @brief Enlève tous les textes du calque courant
        *  @return void
        */
        public void clear_texte()
        {
            this.logiciel.clear_texte();
        }


        /**
         * lancer_recherche
         * 
         * @brief lance une recherche pour retrouver une/des annotation(s)
         * @param bool recherche_dans_balise : indique si l'on cherche l'annotation dans les balises
         * @param bool recherche_dans_encre : indique si l'on cherche l'annotation dans les encres
         * @param bool recherche_dans_texte : indique si l'on cherche l'annotation dans les textes            
         * @params string mot_cle : le mot-clef associée à l'annotation recherchée  
         * @param string auteur : le nom de l'auteur de l'annotation recherchée                                           
         * @param bool rechercheCalqueCourant : indique si l'on recherche uniquement dans le calque courant
         * @return List<System.Drawing.Point> : la liste des annotation correspondants aux critères de recherche
        */
        public List<System.Drawing.Point> lancer_recherche(bool recherche_dans_balise, bool recherche_dans_encre,
                                                      bool recherche_dans_texte, string mot_cle, string auteur,
                                                      bool rechercheCalqueCourant)
        {
           return logiciel.lancer_recherche(recherche_dans_balise,recherche_dans_encre,recherche_dans_texte,
                                            mot_cle, auteur, rechercheCalqueCourant);
        }


        /**
         * lancer_recherche
         * 
         * @brief lance une recherche pour retrouver une/des annotation(s)
         * @param bool recherche_dans_balise : indique si l'on cherche l'annotation dans les balises
         * @param bool recherche_dans_encre : indique si l'on cherche l'annotation dans les encres
         * @param bool recherche_dans_texte : indique si l'on cherche l'annotation dans les textes            
         * @params Semantique sem : la sémantique associée aux annotations recherchées                                          
         * @param bool rechercheCalqueCourant : indique si l'on recherche uniquement dans le calque courant
         * @return List<System.Drawing.Point> : la liste des annotation correspondants aux critères de recherche
        */
        public List<System.Drawing.Point> lancer_recherche(bool recherche_dans_balise,bbool recherche_dans_encre,
                                                      bool recherche_dans_texte, Modele.Semantique sem,
                                                      bool rechercheCalqueCourant)
        {
            return logiciel.lancer_recherche(recherche_dans_balise, recherche_dans_encre, recherche_dans_texte,
                                              sem, rechercheCalqueCourant);
        }


        /**
         * sauver
         * 
         * @brief sauvegarde le projet courant
         * @param string nomFichier : le nom que l'on souhaite donner au projet courant
         * @return void
        */
        public void sauver(String nomFichier)
        {
            logiciel.sauver(nomFichier);
        }


        /**
         * ouvrir
         * 
         * @brief ouvrir un projet PAN existant
         * @param string nomFichier : le nom du projet PAN que l'on souhaite ouvrir
         * @return void
        */
        public Bitmap ouvrir(String nomFichier)
        {
            return logiciel.ouvrir(nomFichier);
        }

        /**
         * changer_vers_blocnote()
         * 
         * @brief passe du projet courant vers son bloc-note
         * @return System.Drawing.Bitmap : l'image de fond du bloc-note
        */
        public System.Drawing.Bitmap changer_vers_blocnote()
        {
            return logiciel.changer_vers_blocnote();
        }

        /**
         * changer_vers_projet()
         * 
         * @brief passe du bloc-note vers le projet auquel il est associé
         * @return System.Drawing.Bitmap : le document annoté
        */
        public System.Drawing.Bitmap changer_vers_projet()
        {
            return logiciel.changer_vers_projet();
        }


        /**
         * getEtatsCalques
         * 
         * @brief permet d'obtenir la liste de bool correspondant aux calques et à leur états associés
         * @return List<bool> : la liste des booléens correspondant à l'état des claques
        */
        public List<bool> getEtatsCalques()
        {
            return logiciel.getEtatsCalques();
        }

        /**
         * getNoms()
         * 
         * @brief permet d'obtenir la liste des noms de calques
         * @return List<string> : la liste des noms des calques
        */
        public List<string> getNoms()
        {
            return logiciel.getNoms();
        }


        /**
          * getNom(int i)
          * 
          * @brief retourne le nom du calque numero i
          * @param int i : le numéro du calque dont l'on veut le nom
          * @return string : le nom du calque i
         */
        public string getNom(int i)
        {
            return logiciel.getNom( i);
        }


        /**
          * setNom(int i, string _nom)
          * 
          * @brief change le nom du claque numero i 
          * @param int i : le numéro du calque dont l'on veut changer le nom
          * @param string _nom : le nom que l'on souhaite attribuer au calque
          * @return void
         */
        public void setNom(int i , string _nom)
        {
            logiciel.setNom(i ,_nom);
        }


        /**
          * setNom(string _nom)
          * 
          * @brief change le nom du claque courant
          * @param string _nom : le nom que l'on souhaite attribuer au calque
          * @return void
         */
         public void setNom(string _nom)
         {
             logiciel.setNom(_nom);
         }


        public Bitmap toImage(System.Drawing.Image image, float zoom)
        {
            return logiciel.toImage(image,zoom);
        }


        /**
          * setDrawingAttributes(Microsoft.Ink.DrawingAttributes _att)
          * 
          * @brief attribut un Microsoft.Ink.DrawingAttributes par défaut à la fenêtre principale
          * @param Microsoft.Ink.DrawingAttributes _att : le nouveau DrawinAttributes ) à assigner
          * @return void
         */
        public void setDrawingAttributes(Microsoft.Ink.DrawingAttributes _att)
        {
            fenetre.setDrawingAttributes(_att);
        }


        /**
          * addKeyWord(string _dialogue)
          * 
          * @brief ajoute un mot clef parmi la liste des mot-clefs disponibles pour la recherche
          * @param string _dialogue : le mot-clef récupéré de la liste de dialogue
         */
        public void addKeyWord(string _dialogue)
        {
            ArrayList keyWordsList;
            keyWordsList = logiciel.addKeyWord(_dialogue);
            fenetre.setComboBoxKeyWords(keyWordsList);
        }


        /**
          * setBibliImages(List<Bitmap> images_balises) 
          * 
          * @brief ajoute une liste d'image (icones) à la bibliothèque des balises
          * @param List<Bitmap> images_balises : les images à ajouter
          * @param void
         */
        public void setBibliImages(List<Bitmap> images_balises) 
        {
            logiciel.setBibliImages(images_balises);
        }


        /**
          * setBibliBalises(List<Modele.Balise> balises)
          * 
          * @brief ajoute une liste de balises à la bibliothèque des balises
          * @param List<Modele.Balise> balises : les balises à ajouter
          * @param void
         */
        public void setBibliBalises(List<Modele.Balise> balises)
        {
            logiciel.setBibliBalises(balises);
        }


        /**
          * getBibliImages()
          * 
          * @brief récupère la liste des icônes de la bibliothèque des balises
          * @return la liste des images (icones) de la bibliothèque des balises
        */
        public List<Bitmap> getBibliImages()
        {
            return logiciel.getBibliImages();
        }


        /**
          * getBibliBalises()
          * 
          * @brief récupère la liste des balises de la bibliothèque des balises
          * @return la liste des balises de la bibliothèque des balises
        */
        public List<Modele.Balise> getBibliBalises()
        {
            return logiciel.getBibliBalises();
        }

    }
}
